/** 
 * @Description: 淹没分析水面绘制工具
 * @Author: 程前
 * @Date: 2025-01-17 13:54:11
 * @LastEditors: 程前
 * @LastEditTime: 2025-01-24 10:00:40
 */

import { Viewer, Primitive, GeometryInstance, PolygonGeometry, EllipsoidSurfaceAppearance, Material, Color, PolygonHierarchy, Cartesian3, Scene, Label, LabelCollection, VerticalOrigin, HorizontalOrigin, LabelStyle, Cartesian2, HeightReference } from 'cesium';
import { polygon as TurfPolygon, centerOfMass as TurfCenterOfMass } from "@turf/turf"
/**
 *  绘制水面
 * @param boundary 边界点位 [112.23, 22.25, 112.24, 22.24]
 * @param waterImg 水面贴图
 * @param extrudedHeight 水面高度
 * @returns 水面实例
 */
export const useDrawRiver = (
  viewer: Viewer,
  boundary: number[],
  waterImg: any,
  extrudedHeight: number
) => {
  try {
    // 验证参数
    if (!viewer || !boundary || boundary.length < 6 || typeof extrudedHeight !== 'number') {
      return null;
    }

    // 验证所有边界点的有效性
    for (let i = 0; i < boundary.length; i++) {
      if (typeof boundary[i] !== 'number' || isNaN(boundary[i])) {
        return null;
      }
    }

    let riverHeight = extrudedHeight;
    let currentRiver: Primitive | null = null;
    let currentLabels: LabelCollection | null = null;

    // 创建标签集合
    currentLabels = new LabelCollection();
    viewer.scene.primitives.add(currentLabels);

    // 计算水面中心点
    let positionList = []
    for (let index = 0; index < boundary.length / 2; index++) {
      const lon = boundary[index * 2];
      const lat = boundary[index * 2 + 1];
      positionList.push([lon, lat]);
    }
    positionList = [...positionList, positionList[0]]
    const polygon = TurfPolygon([positionList]);
    const centerOfMass = TurfCenterOfMass(polygon).geometry.coordinates;

    // 创建高度标签
    const heightLabel = currentLabels.add({
      position: Cartesian3.fromDegrees(centerOfMass[0], centerOfMass[1], riverHeight),
      text: `水面高度: ${riverHeight}米`,
      font: '20px sans-serif',
      fillColor: Color.WHITE,
      outlineColor: Color.BLACK,
      outlineWidth: 2,
      style: LabelStyle.FILL_AND_OUTLINE,
      verticalOrigin: VerticalOrigin.CENTER,
      horizontalOrigin: HorizontalOrigin.CENTER,
      disableDepthTestDistance: Number.POSITIVE_INFINITY,
      pixelOffset: new Cartesian2(0, 0),
      scale: 1.0
    });

    // 创建水面材质
    const riverMaterial = new Material({
      fabric: {
        type: "Water",
        uniforms: {
          blendColor: new Color(0.0, 0.0, 1.0, 0.2),
          normalMap: waterImg,
          frequency: 500.0,
          animationSpeed: 0.05,
          amplitude: 10.0
        }
      }
    });

    // 创建水面函数
    const createRiverPrimitive = (height: number) => {
      const polygon = useCreatePolygonGeometry(boundary, height);
      if (!polygon) return null;

      const primitive = new Primitive({
        geometryInstances: new GeometryInstance({
          geometry: polygon,
        }),
        appearance: new EllipsoidSurfaceAppearance({
          aboveGround: true,
        }),
        show: true,
        asynchronous: false,
        releaseGeometryInstances: false,
      });

      primitive.appearance.material = riverMaterial;
      return primitive;
    };

    // 初始创建水面
    currentRiver = createRiverPrimitive(riverHeight);
    if (currentRiver) {
      viewer.scene.primitives.add(currentRiver);
    }

    // 创建代理对象来处理高度更新
    const riverProxy = {
      get extrudedHeight() {
        return riverHeight;
      },
      set extrudedHeight(newVal: number) {
        if (typeof newVal !== 'number' || isNaN(newVal)) {
          console.error(newVal);
          return;
        }

        riverHeight = Number(newVal.toFixed(2));

        // 移除旧的水面
        if (currentRiver) {
          viewer.scene.primitives.remove(currentRiver);
        }

        // 创建新的水面
        currentRiver = createRiverPrimitive(riverHeight);
        if (currentRiver) {
          viewer.scene.primitives.add(currentRiver);
        }

        // 更新标签
        const newPosition = Cartesian3.fromDegrees(centerOfMass[0], centerOfMass[1], riverHeight);
        heightLabel.position = newPosition;
        heightLabel.text = `水面高度: ${riverHeight}米`;
      },
      destroy() {
        if (currentRiver) {
          viewer.scene.primitives.remove(currentRiver);
          currentRiver = null;
        }
        if (currentLabels) {
          viewer.scene.primitives.remove(currentLabels);
          currentLabels = null;
        }
      }
    };

    return riverProxy;
  } catch (error) {
    console.error(error);
    return null;
  }
};

const useCreatePolygonGeometry = (boundary: number[], extrudedHeight: number) => {
  try {
    // 验证参数
    if (!boundary || boundary.length < 6 || typeof extrudedHeight !== 'number' || isNaN(extrudedHeight)) {
      return null;
    }

    const polygon = new PolygonGeometry({
      polygonHierarchy: new PolygonHierarchy(Cartesian3.fromDegreesArray(boundary)),
      extrudedHeight,
      vertexFormat: EllipsoidSurfaceAppearance.VERTEX_FORMAT,
    });

    return polygon;
  } catch (error) {
    console.error(error);
    return null;
  }
};

